Q: ムービーが実際に 非 RGB GWorld へ描画できることを確認できますか?たとえば、'2vuy' (k2vuyPixelFormat ) ピクセル形式の GWorld を作成した場合、一部のムービーだけはこの形式で描画されますが、それ以外は単に空のフレームが描画されるようです。
A: 2 つの方法で、非 RGB GWorld にムービーを描画できるかどうかを確認できます。
すべてのイメージデコンプレッサが非 RGB 出力をサポートするわけではありません。複数のビデオトラック、エフェクト、複数のコーデック型、変換マトリックスなどを持つ複雑なムービーは、QuickTime が非 RGB の色空間では表現できないさまざまな合成を必要とします。
1 つ目の方法は、合成または複雑なマトリックスを含まず、1 つのイメージ記述をもつビデオトラックがムービーに 1 つしかなく、そのビデオ形式が出力先として非 RGB ピクセル形式をサポートするかどうかを確かめて、ムービーの単純性を調べます。リスト 1 を参照してください。
注記: この方法は、非 RGB ピクセル形式に描画できる一部のムービーを受け付けないことがあります。 |
リスト 1. 指定されたピクセル形式にムービーを描画できるかどうか |
Boolean CanRenderMovieToPixelFormat(Movie inMovie,
OSType inPixelFormat)
{
Track videoTrack, secondVisualTrack;
ImageDescriptionHandle imageDesc = NULL;
Boolean canRenderNonRGB = false;
MatrixRecord matrix;
Media videoMedia;
OSType codecType;
ComponentDescription cd = { decompressorComponentType, 0, 0, 0,
cmpIsMissing };
Component decompressor = 0;
// 値 1、2、4、8、16、24、32 は標準 RGB ピクセル形式を指定し、
// 値 33、34、36、40 は標準グレースケールのピクセル形式を指定する。
// これらのピクセル形式には、このアプローチは使用しないこと
if (inPixelFormat <= 40) return true;
// ムービーのマトリックスが「scale」+「translate」と同じかどうかチェック
GetMovieMatrix(inMovie, &matrix);
if (GetMatrixType(&matrix) > scaleTranslateMatrixType) goto nope;
// 1 つ目のビデオトラックを取得
videoTrack = GetMovieIndTrackType(inMovie, 1, VideoMediaType,
movieTrackMediaType);
if (!videoTrack) goto nope;
// ほかのビジュアルトラックがないことを確認
// (ビデオトラックは常にビジュアル)
secondVisualTrack = GetMovieIndTrackType(inMovie, 2,
VisualMediaCharacteristic,
movieTrackCharacteristic);
if (secondVisualTrack) goto nope;
// ビデオトラックのマトリックスが「scale」+「translate」と同じかどうかチェック
GetTrackMatrix(videoTrack, &matrix);
if (GetMatrixType(&matrix) > scaleTranslateMatrixType) goto nope;
// サンプル記述が 1 つしかないことを確認
videoMedia = GetTrackMedia(videoTrack);
if (1 != GetMediaSampleDescriptionCount(videoMedia)) goto nope;
// そのサンプル記述からコーデック型を取得
imageDesc = (ImageDescriptionHandle)NewHandle(0);
GetMediaSampleDescription(videoMedia, 1,
(SampleDescriptionHandle)imageDesc);
if (noErr != GetMoviesError()) goto nope;
codecType = (*imageDesc)->cType;
// このコーデック型のデコンプレッサを見つける。cpix パブリックリソースに、
// 一致するピクセル形式がリストされているものを、少なくとも 1 つ見つける
cd.componentSubType = codecType;
decompressor = FindNextComponent(0, &cd);
if (!decompressor) goto nope;
do {
Handle cpix = NULL;
// 'cpix' リソースは、サポートされている非 RGB ピクセル形式をリストする
// ために、コーデックによって使用される
if (noErr == GetComponentPublicResource(decompressor,
FOUR_CHAR_CODE('cpix'), 1, &cpix)) {
int i;
int cpixFormatCount = GetHandleSize(cpix) / sizeof(OSType);
for (i = 0; i < cpixFormatCount; i++) {
if (inPixelformat == (*(OSType**)cpix)[i]) {
canRenderNonRGB = true;
}
}
DisposeHandle( cpix );
}
decompressor = FindNextComponent(decompressor, &cd);
} while (decompressor && false == canRenderNonRGB);
nope:
if (imageDesc) DisposeHandle((Handle)imageDesc);
return canRenderNonRGB;
}
|
もう 1 つの方法では、指定されたピクセル形式への描画を試み、それが成功したかどうかを調べます。リスト 2 を参照してください。
警告: クラッシュして失敗する恐れがあるので、この方法を QuickTime 6 以前のバージョンで使用するべきではありません。 |
リスト 2. 指定されたピクセル形式へのムービーの描画実行 |
OSErr TryToRenderMovieToPixelFormat(Movie inMovie,
OSType inPixelFormat)
{
OSErr err;
Rect bounds;
CGrafPtr savePort;
GDHandle saveDevice;
GWorldPtr gworld = NULL;
GetMovieGWorld(inMovie, &savePort, &saveDevice);
GetMovieBox(inMovie, &bounds);
err = QTNewGWorld(&gworld, inPixelFormat, &bounds, NULL, NULL, 0);
if (err) goto bail;
LockPixels(GetGWorldPixMap(gworld));
SetMovieGWorld(inMovie, gworld, NULL);
MoviesTask(inMovie, 0);
err = GetMovieStatus(inMovie, NULL);
bail:
SetMovieGWorld(inMovie, savePort, saveDevice);
if (gworld) DisposeGWorld(gworld);
return err;
}
|
ムービーを特定の非 RGB GWorld に描画できることを確認するときには、上記のテクニックを両方とも使うことをお勧めします。まず、ムービーが目的のピクセル形式への描画をサポートするかどうかを確認し、次に、実際に描画してみます。どちらかの手順が失敗した場合は、32ARGB (k32ARGBPixelFormat ) GWorld に戻ります。
[2003 年 3 月 5 日] |